home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / qlib205.zip / QLIB.ZIP / SRC / GRAFIX / VESA.ASM < prev    next >
Assembly Source File  |  1997-04-12  |  12KB  |  558 lines

  1. ; Simple VESA Driver
  2. ; Version 2.00  (from video.asm in QLIB v1.2)
  3.  
  4. ; Supports : VESA 2.0 and 1.2 fully
  5.  
  6. .data?
  7. bankshift db ?
  8. align 4
  9. PmodeSetStart           DD ?
  10. ProgramBaseAddress      DD ?
  11. vesamode                DW ?
  12. Total64Kblocks          DW ?
  13. vesa_current_bank       DB ?
  14. VBE_StarPerPixelFactor  DB ?
  15. vesa_ver                DW ?
  16. vesa_info vesa_infoblock <>
  17. vesa_modeinfo vesa_modeinfoblock <>
  18.  
  19. .data
  20. vesa_list               dd 0  ;list of video modes
  21. vesa_list_pos           dd 0  ;current POS when using first/next mode()
  22.  
  23. align 4
  24. vbesetbank              DD Offset SetBank_RealMode
  25. vesa_setstart_proc      DD Offset SetStart_RealMode
  26.  
  27. _800_ DD 0      ;this is the linear addr returned by DPMI func #800h
  28.  
  29. std_list label word   ;VESA standard video mode list
  30.   dw 10fh
  31.   dw 112h
  32.   dw 104h
  33.   dw 0ffffh
  34.  
  35. .code
  36. vesa_uninit proc private
  37.   .if _800_
  38.     pushad
  39.     mov ax,801h
  40.     mov bx,wptr cs:[_800_+2]
  41.     mov cx,wptr cs:[_800_]
  42.     int 31h
  43.     mov _800_,0
  44.     popad
  45.   .endif
  46.   mov exitmode,NULLPROC
  47.   ret
  48. vesa_uninit endp
  49.  
  50. vesa_init proc
  51.   pushad
  52.  
  53.   mov ax,_8kbufferseg
  54.   mov _es_,ax
  55.   mov ax,4F00h
  56.   xor edi,edi   ; (real mode) ES:DI -> 256 byte buffer
  57.   int 10h       ;  GET VESA INFORMATION
  58.    ;c0.asm always loads DS,ES in RMODE with _es_,_ds_
  59.    ;      when using int  10h
  60.   cmp ax,004Fh
  61.   jne bad
  62.   mov esi,_8kbuffer
  63.   mov edi,offset vesa_info
  64.   mov ecx,512/4
  65.   rep movsd
  66.  
  67.   mov dx,vesa_info.VbeVersion
  68.   mov vesa_ver,dx
  69.  
  70.   mov dx,vesa_info.TotalMemory
  71.   mov Total64Kblocks,dx
  72.  
  73.   xor edx,edx
  74.   mov dx,wptr [vesa_info.VideoModePtr + 2]
  75.   xor ebx,ebx
  76.   mov bx,wptr [vesa_info.VideoModePtr]
  77.   .if dx==_8kbufferseg  ;some VESA BIOS return the list right in the vesa_info block
  78.     mov edx,offset vesa_info
  79.     add edx,ebx
  80.   .else
  81.     shl edx,4
  82.     add edx,ebx                 ; EDX points to video mode list.
  83.   .endif
  84.   mov vesa_list,edx
  85.  
  86.   popad
  87.   xor eax,eax
  88.   mov ax,vesa_ver
  89.   ret
  90. bad:  ;Vesa not detected
  91.   popad
  92.   mov eax,ERROR
  93.   ret
  94. vesa_init endp
  95.  
  96. getinfo proc private,mode:word
  97.   mov ax,_8kbufferseg
  98.   mov _es_,ax
  99.   mov ax,4F01h
  100.   mov cx,mode
  101.   and cx,01ffh                     ; read bits 0..8
  102.   xor edi,edi                      ; ES:DI -> 256 byte buffer
  103.   int 10h
  104.   cmp ax,004Fh
  105.   .if !zero?
  106.     mov eax,ERROR
  107.     ret
  108.   .endif
  109.   mov esi,_8kbuffer
  110.   mov edi,offset vesa_modeinfo
  111.   mov ecx,256/4
  112.   rep movsd
  113.   xor eax,eax
  114.   ret
  115. getinfo endp
  116.  
  117. vesa_getmode PROC private,x:word,y:word,bpp:byte
  118.  
  119.   local using_std:byte
  120.  
  121.   .if !vesa_list
  122.     mov eax,ERROR
  123.     ret
  124.   .endif
  125.  
  126.   pushad
  127.  
  128.      ;
  129.      ; Search video mode list for the required mode.
  130.      ; The vesa driver Func 4F00h fills in the buffer with the information.
  131.      ; Offset 0Eh of this buffer contains a real mode SEG:OFS of the video
  132.      ; mode list. This list consists of each supported VESA mode and
  133.      ; terminates with 0FFFFh.
  134.      ;
  135.  
  136.      ; Get the real mode far pointer of the video mode list and
  137.      ; convert the real mode SEG:OFS address into a 32bit near pointer.
  138.  
  139.   mov using_std,0
  140.   mov edx,vesa_list
  141.   xor eax,eax
  142. @@:
  143.   mov   ax,[edx]                     ; Read video mode from list
  144.   cmp   ax,0FFFFh
  145.   .if zero?
  146.     .if using_std
  147.       jmp bad
  148.     .endif
  149.     inc using_std  ;set using_std
  150.     mov edx,offset std_list
  151.     jmp @b
  152.   .endif
  153.   push edx
  154.   callp getinfo,ax  ;does not preserve regs
  155.   pop edx
  156.  
  157.   mov ax,vesa_modeinfo.WinSize
  158.   cmp ax,64
  159.   jnz try_next   ;require 64K window sizes  (this should never be a problem)
  160.  
  161.   mov ax,vesa_modeinfo.ModeAttributes
  162.   test ax,1
  163.   jz try_next  ;hardware does not support this mode
  164.   mov al,vesa_modeinfo.WinAAttributes
  165.   and al,0110b
  166.   cmp al,0110b
  167.   jnz try_next        ;mode not supported or not usable
  168.  
  169.   mov ax,vesa_modeinfo.XResolution
  170.   .if ax!=x
  171.     jmp try_next
  172.   .endif
  173.   mov ax,vesa_modeinfo.YResolution
  174.   .if ax!=y
  175.     jmp try_next
  176.   .endif
  177.   mov al,vesa_modeinfo.BitsPerPixel
  178.   .if al!=bpp
  179.     jmp try_next
  180.   .endif
  181.  
  182. ;current mode is acceptable
  183.   mov ax,[edx]
  184.   mov vesamode,ax
  185.   jmp @f
  186.  
  187. try_next:
  188.   add edx,2
  189.   jmp @b
  190.  
  191. bad:
  192.   popad
  193.   mov eax,ERROR
  194.   ret
  195.  
  196. @@:
  197.   ;setup X/Y/BPP values
  198.   ;Get bytes per scan line for the protected mode SetStart function.
  199.   ;this is also used by v_copy
  200.  
  201.   xor eax,eax
  202.   mov ax,vesa_modeinfo.BytesPerScanLine
  203.   mov getmode_bpsl,ax
  204.  
  205.   popad
  206.   mov eax,1  ;linear mode
  207.   Test vesa_modeinfo.ModeAttributes ,10000000b  ;linear avail?
  208.   .if zero?
  209.     mov eax,0  ;banking mode
  210.   .endif
  211.   ret
  212. vesa_getmode endp
  213.  
  214. vesa_setmode proc private
  215.   ; Set VIDEO mode
  216.   .if !vesamode
  217.     mov eax,ERROR
  218.     ret
  219.   .endif
  220.   pushad
  221.  
  222.   ; ******************************************************
  223.   ; Setup for linear memory mapping mode.
  224.   ; ******************************************************
  225.  
  226.   Test vesa_modeinfo.ModeAttributes ,10000000b  ;linear avail?
  227.   jz DoWithBanks
  228.  
  229.   ;
  230.   ; Calulate a near pointer to physical linear mapping address.
  231.   ;
  232.  
  233.   add    vesamode,4000h
  234.  
  235.   Mov    ebx,vesa_modeinfo.PhysBasePtr
  236.   mov    cx,bx
  237.   shr    ebx,16
  238.   mov    si,Total64Kblocks
  239.   xor    edi,edi
  240.   mov    ax,0800h                ; map physical memory
  241.   int    31h
  242.   jc     bad
  243.   shl    ebx,16
  244.   mov    bx,cx
  245.   mov    eax,ebx                 ; eax = linear address
  246. @@:
  247.   mov    _800_,eax
  248.   mov    _v_linear,eax
  249.   jmp    Finished
  250.  
  251. DoWithBanks:
  252.  
  253.   ; ******************************************************
  254.   ; Setup for windowing mode.
  255.   ; ******************************************************
  256.  
  257.   ; check is windowing is avalible ( writable and readable )
  258.   Test  vesa_modeinfo.ModeAttributes ,01000000b   ;available?
  259.   jnz   bad
  260.  
  261.     ;
  262.     ; Setup Bank Shift number  (I got idea from Dr. Dobbs)
  263.     ;
  264.  
  265.   Movzx  ebx,vesa_modeinfo.WinGranularity
  266.   xor    edx,edx   ;bankshift
  267.   mov ecx,64
  268.   .while (ecx != ebx)
  269.     inc edx
  270.     shr ecx,1
  271.   .endw
  272.   mov bankshift,dl  ;used in vesa_setbank proc
  273.  
  274.      ;
  275.      ; Calulate 32bit linear pointer to CPU video memory WindowA
  276.      ;
  277.  
  278.   Movzx eax,vesa_modeinfo.WinASegment
  279.   shl eax,4
  280.   mov _v_linear,eax
  281.  
  282. Finished:
  283.  
  284.     ;
  285.     ; If 32bit VBE inteface is availible then use it
  286.     ;
  287.  
  288.   mov ax,4f0ah
  289.   mov bl,0                 ; return pmode interface
  290.   int 10h
  291.   cmp ax,004fh
  292.   jne No32bitInterface
  293.   xor esi,esi
  294.   mov si,_es_          ; convert ES:DI to 32bit near ptr
  295.   shl esi,4
  296.   movzx edi,di
  297.   add esi,edi
  298.  
  299.      ; Use protected mode bank proc only for zero length memory list.
  300.  
  301.   movzx  edi,word ptr [ESI+06]      ; get port/memory table list
  302.   and    edi,edi
  303.   jz     @@usePmodeBanks
  304.  
  305. @@:
  306.   cmp    word Ptr [ESI+EDI],0FFFFh  ; search port list
  307.   lea    edi,[edi+2]
  308.   jne @b
  309.   cmp    Word Ptr [ESI+EDI],0FFFFh  ; see if mem list is zero
  310.   jne    @@SkipPmodeBanks
  311.  
  312. @@usePmodeBanks:
  313.   movzx  eax,Word Ptr [ESI+00]
  314.   add    eax,esi
  315.   mov    [vbesetbank],eax         ; save Set Bank code address.
  316.  
  317. @@SkipPmodeBanks:
  318.  
  319.   ; Save Set display start code address.
  320.  
  321.   movzx  eax,Word Ptr [ESI+02]
  322.   add    eax,esi
  323.   mov    [PmodeSetStart],eax
  324.   mov    [vesa_setstart_proc],Offset SetStart_ProtectedMode
  325.  
  326.   ; adjust for plane boundary for 8 bit+ modes
  327.  
  328.   mov    [VBE_StarPerPixelFactor],0
  329.   Cmp    [vesa_modeinfo.BitsPerPixel],4
  330.   je @f
  331.   mov    [VBE_StarPerPixelFactor],2
  332. @@:
  333.   jmp @f
  334.  
  335. No32bitInterface:
  336.   mov vbesetbank,Offset SetBank_RealMode
  337.   mov vesa_setstart_proc,Offset SetStart_RealMode
  338.  
  339. @@:
  340.   xor eax,eax
  341.   xor ebx,ebx
  342.   xor ecx,ecx
  343.   xor edx,edx
  344.   mov bx,vesamode
  345.   mov ax,4f02h
  346.   int 10h
  347.   mov exitmode,offset vesa_uninit
  348.  
  349.   popad   ;EAX will be poped off
  350.   xor eax,eax
  351.   ret
  352.  
  353. bad:
  354.   popad
  355.   mov eax,ERROR
  356.   ret
  357. vesa_setmode ENDP
  358.  
  359. vesa_firstmode proc
  360.   mov eax,vesa_list
  361.   .if !eax
  362.     mov eax,ERROR
  363.     ret
  364.   .endif
  365.   pushad
  366.   mov edx,eax
  367. @@:
  368.   mov ax,[edx]
  369.   .if ax==0ffffh
  370.     mov vesa_list_pos,edx
  371.     popad
  372.     mov eax,ERROR
  373.     ret
  374.   .endif
  375.   push edx
  376.   callp getinfo,ax
  377.   pop edx
  378.  
  379.   mov ax,vesa_modeinfo.WinSize
  380.   cmp ax,64
  381.   jnz bad        ;require 64K window sizes  (this should never be a problem)
  382.  
  383.   mov al,vesa_modeinfo.WinAAttributes
  384.   and al,0110b   ;mode read/write able?
  385.   cmp al,0110b
  386.   jnz bad
  387.  
  388.   mov ax,vesa_modeinfo.ModeAttributes
  389.   test ax,1
  390.   jz bad        ;mode not supported or not usable
  391.  
  392.   mov vesa_list_pos,edx
  393.   popad
  394.  
  395.   xor eax,eax
  396.   ret
  397.  
  398. bad:
  399.   add edx,2
  400.   jmp @b
  401. vesa_firstmode endp
  402.  
  403. vesa_nextmode proc
  404.   pushad
  405.   mov edx,vesa_list_pos
  406.   .if !edx
  407.     popad
  408.     mov eax,ERROR
  409.     ret
  410.   .endif
  411.   mov ax,[edx]
  412.   .if ax==0ffffh
  413.     jmp bad
  414.   .endif
  415.   add edx,2  ;next
  416. @@:
  417.   mov ax,[edx]
  418.   .if ax==0ffffh
  419.     mov vesa_list_pos,edx
  420. bad:
  421.     popad
  422.     mov eax,ERROR
  423.     ret
  424.   .endif
  425.   push edx
  426.   callp getinfo,ax
  427.   pop edx
  428.  
  429.   mov ax,vesa_modeinfo.WinSize
  430.   cmp ax,64
  431.   jnz bad        ;require 64K window sizes  (this should never be a problem)
  432.  
  433.   mov al,vesa_modeinfo.WinAAttributes
  434.   and al,0110b   ;mode read/write able?
  435.   cmp al,0110b
  436.   jnz next
  437.  
  438.   mov ax,vesa_modeinfo.ModeAttributes
  439.   test ax,1
  440.   jz next        ;mode not supported or not usable
  441.  
  442.   mov vesa_list_pos,edx
  443.   popad
  444.   xor eax,eax
  445.   ret
  446.  
  447. next:
  448.   add edx,2
  449.   jmp @b
  450. vesa_nextmode endp
  451.  
  452. ;Alway consider each back to be 64K and will never overlay
  453. ;(regardless of current hardware)
  454. ;this driver will simulate the non-overlaping 64K banks
  455.  
  456. vesa_setbank PROC private,banknum:byte
  457.   mov    al,banknum
  458.   cmp    vesa_current_bank,al
  459.   jz     @f
  460.   pushad
  461.   mov dl,al
  462.   and    edx,01fh
  463.   mov    vesa_current_bank,dl
  464.   mov    cl,bankshift
  465.   shl    edx,cl
  466.   xor    ebx,ebx
  467.   call   [vbesetbank]
  468.   popad
  469. @@:
  470.   xor eax,eax
  471.   ret
  472. vesa_setbank ENDP
  473.  
  474. vesa_nextbank PROC private
  475.   pushad
  476.   xor    edx,edx
  477.   mov    dl,vesa_current_bank
  478.   inc    dl
  479.   mov    vesa_current_bank,dl
  480.   mov    cl,bankshift
  481.   shl    edx,cl
  482.   xor    ebx,ebx
  483.   call   [vbesetbank]
  484.   popad
  485.   xor eax,eax
  486.   ret
  487. vesa_nextbank ENDP
  488.  
  489. ;  VBE Function 06h - Set/Get Logical Scan Line Length
  490. ; You must call this when using Func #6 (the driver needs the BX returned from VESA)
  491. vesa_func06 PROC
  492.   mov  ax,4F06h
  493.   int  10h
  494.   cmp  ah,00h
  495.   jne  @f
  496.   mov  wptr[_v_bpsl],bx
  497. @@:
  498.   ret
  499. vesa_func06 ENDP
  500.  
  501. ;***********************************************************
  502. ; Call real mode set video bank function
  503. ; Note: very very slow....
  504. ;***********************************************************
  505. SetBank_RealMode PROC private
  506.         push   ebx
  507.         xor    ebx,ebx
  508.         mov    ax,04F05h
  509.         int    10h
  510.         pop    ebx
  511.         Ret
  512. SetBank_RealMode ENDP
  513.  
  514. ;--------------------------------------------------------
  515. ; Call real mode set display start bank function
  516. ; CX=pixel in scan line
  517. ; DX=scan line number
  518. ; Note: very very slow....
  519. ;----------------------------------------------------------
  520. SetStart_RealMode PROC private
  521.         push   ebx
  522.         xor    ebx,ebx
  523.         mov    ax,04F07h
  524.         int    10h
  525.         pop    ebx
  526.         Ret
  527. SetStart_RealMode ENDP
  528.  
  529. ;--------------------------------------------------------
  530. ; Call Protected mode set display start bank function
  531. ; ECX=pixel in scan line
  532. ; EDX=scan line number
  533. ;----------------------------------------------------------
  534. SetStart_ProtectedMode PROC private
  535.         push   ebx
  536.         xor    ebx,ebx
  537.         imul   edx,[_v_bpsl]
  538.         add    edx,ecx
  539.         mov    cl,[VBE_StarPerPixelFactor]
  540.         shr    edx,cl
  541.         mov    cx,dx
  542.         shr    edx,16
  543.         mov    ax,04F07h
  544.         Call   [PmodeSetStart]
  545.         pop    ebx
  546.         Ret
  547. SetStart_ProtectedMode ENDP
  548.  
  549. vesa_setstart proc,start:dword,scan:dword
  550.   pushad
  551.   mov ecx,start
  552.   mov edx,scan
  553.   call vesa_setstart_proc
  554.   popad
  555.   ret
  556. vesa_setstart endp
  557.  
  558.